package com.ugoodtech.mdcc.client.service.impl;

/* Copyright (C) Ugoodtech, Inc - All Rights Reserved.
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 * Proprietary and confidential.
 * Written by Stone Shaw.
 */

import com.google.common.collect.Lists;
import com.mysema.query.BooleanBuilder;
import com.ugoodtech.mdcc.client.common.BizConstants;
import com.ugoodtech.mdcc.client.dto.BrandVO;
import com.ugoodtech.mdcc.client.dto.LocationVO;
import com.ugoodtech.mdcc.client.dto.UserAuthorityVO;
import com.ugoodtech.mdcc.client.dto.UserDepartmentVO;
import com.ugoodtech.mdcc.client.dto.UserDetailVO;
import com.ugoodtech.mdcc.client.exception.BizException;
import com.ugoodtech.mdcc.client.exception.EnumBizError;
import com.ugoodtech.mdcc.client.service.UserService;
import com.ugoodtech.mdcc.core.domain.Brand;
import com.ugoodtech.mdcc.core.domain.Department;
import com.ugoodtech.mdcc.core.domain.ModuleAuthority;
import com.ugoodtech.mdcc.core.domain.Nation;
import com.ugoodtech.mdcc.core.domain.QUserProfile;
import com.ugoodtech.mdcc.core.domain.Station;
import com.ugoodtech.mdcc.core.domain.User;
import com.ugoodtech.mdcc.core.domain.UserProfile;
import com.ugoodtech.mdcc.core.domain.UserType;
import com.ugoodtech.mdcc.core.repository.UserProfileRepository;
import com.ugoodtech.mdcc.core.repository.UserRepository;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.tomcat.jdbc.pool.ConnectionPool;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.ugoodtech.mdcc.client.common.BizConstants.Authority.PLATFORM_WECHAT;

@Service
public class UserServiceImpl implements UserService, UserDetailsService {
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserProfileRepository userProfileRepository;

    @Autowired
    private DataSource dataSource;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        System.out.println("search user " + username);

        try {
            ConnectionPool pool = dataSource.getPool();
//                System.out.println(pool.getActive());
            Connection conn = pool.getConnection();
//                System.out.println(pool.getActive());

            PreparedStatement ps = conn.prepareStatement("delete from oauth_access_token where user_name = ?");
            ps.setString(1, username);
            ps.executeUpdate();
            conn.close();
            System.out.println("reset access_token for username:" + username);
        } catch (Exception e) {
            e.printStackTrace();

        }


        if (user == null) {
            throw new UsernameNotFoundException("user with username " + username + " not found!");
        } else if (!user.isEnabled()) {
            throw new UsernameNotFoundException("user disabled");
        } else if (user.isDeleted()) {
            throw new UsernameNotFoundException("user not exist");
        }
        return user;
    }

    @Override
    public boolean modifyPassword(User user, String oldPwd, String newPwd) {
        if (passwordEncoder.matches(oldPwd, user.getPassword())) {
            user.setPassword(passwordEncoder.encode(newPwd));
            userRepository.save(user);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean changePassword(User user, String newPwd) {
        user.setPassword(passwordEncoder.encode(newPwd));
        userRepository.save(user);
        return true;
    }

    @Override
    public Page<User> queryUser(Nation nation, Pageable pageable) {
        return null;
    }

    @Override
    public Page<User> queryUser(String key, Boolean enabled, String roleName, Date startDate, Date endDate, Pageable pageable, User currentUser) {
        return null;
    }

//    @Override
//    public Page<User> findUserWhoFollow(User user, Pageable pageable) {
//        QUser qUser = QUser.user;
//        BooleanBuilder builder = new BooleanBuilder();
//        builder.and(qUser.deleted.eq(false));
//        builder.and(qUser.enabled.eq(true));
//        if (null != user) {
//            builder.and(qUser.followUsers.contains(user));
//            builder.and(qUser.id.ne(user.getId()));
//        }
//
//        return userRepository.findAll(builder, pageable);
//    }

//    @Override
//    public Page<User> queryUser(Nation nation, Role role, Pageable pageable) {
//        QUser qUser = QUser.user;
//        BooleanBuilder builder = new BooleanBuilder();
//        builder.and(qUser.deleted.eq(false));
//        builder.and(qUser.enabled.eq(true));
////        if (null != nation) {
////            builder.and(qUser.nations.contains(nation));
////        }
//        if (null != role) {
//            builder.and(qUser.role.id.eq(role.getId()));
//        }
//        return userRepository.findAll(builder, pageable);
//    }

//    @Override
//    public Page<User> queryUser(String key, Boolean enabled, String roleName, Date startDate, Date endDate,  Department department, Pageable pageable,User currentUser) {
//        QUser qUser = QUser.user;
//        BooleanBuilder builder = new BooleanBuilder();
//        builder.and(qUser.deleted.isFalse());
//        if (!StringUtils.isEmpty(key)) {
//            BooleanBuilder orBuilder = new BooleanBuilder();
//            orBuilder.or(qUser.username.like("%" + key + "%"));
////            orBuilder.or(qUser.realName.like("%" + key + "%"));
////            orBuilder.or(qUser.telephone.like("%" + key + "%"));
////            orBuilder.or(qUser.goodAtDisease.like("%" + key + "%"));
////            orBuilder.or(qUser.hospital.name.like("%" + key + "%"));
////            orBuilder.or(qUser.department.name.like("%" + key + "%"));
////            orBuilder.or(qUser.hospitalName.like("%" + key + "%"));
//
//            builder.and(orBuilder);
//        }
//        if (null != enabled) {
//            builder.and(qUser.enabled.eq(enabled));
//        }
//        if (!StringUtils.isEmpty(roleName)) {
//            builder.and(qUser.roles.any().name.eq(roleName));
//        }
//
//        if (enabled != null) {
//            builder.and(qUser.enabled.eq(enabled));
//        }
//
//
//        if (null != startDate) {
//            builder.and(qUser.activateTime.after(startDate));
//        }
//
//        if (null != endDate) {
//            builder.and(qUser.activateTime.before(endDate));
//        }
//
//        if (null != hospital) {
//            builder.and(qUser.hospital.id.eq(hospital.getId()));
//        }
//        if (null != department) {
//            builder.and(qUser.department.id.eq(department.getId()));
//        }
//        if(null!=currentUser){
//            if(currentUser.getRoleNames().contains(Constants.ROLE_NORMAL_USER)){
//                if(currentUser.getNationType().equals(NationType.dingNan)){
//                    builder.and(qUser.nationType.ne(NationType.notDingNan));
//                }
//                if(currentUser.getNationType().equals(NationType.notDingNan)){
//                    builder.and(qUser.nationType.ne(NationType.dingNan));
//                }
//            }
//        }
//
//        return userRepository.findAll(builder, pageable);
//    }

//    @Override
//    public User createThirdUser(String username, String password, String sex, String nickname, String avatar, User.RegistrationWay phoneNumberRegister) {
//        String encodePwd = passwordEncoder.encode(password);
//        User user = new User(username, encodePwd);
//        user.setOpenId(username);
//        user.setSex(sex);
//        user.setRealName(nickname);
//        user.setAvatar(avatar);
//        if (User.RegistrationWay.WEI_XIN_REGISTER.equals(phoneNumberRegister)) {
//            user.setAvatarType(User.AvatarType.WEI_XIN_TYPE);
//        } else if (User.RegistrationWay.LINKEDIN_REGISTER.equals(phoneNumberRegister)) {
//            user.setAvatarType(User.AvatarType.LINKEDIN_TYPE);
//        } else if (User.RegistrationWay.FACEBOOK_REGISTER.equals(phoneNumberRegister)) {
//            user.setAvatarType(User.AvatarType.FACEBOOK_TYPE);
//        } else if (User.RegistrationWay.GOOGLE_REGISTER.equals(phoneNumberRegister)) {
//            user.setAvatarType(User.AvatarType.GOOGLE_TYPE);
//        }
//        user.setSex(sex);
//        user.setDeleted(false);
//        user.setEnabled(true);
//        user.setCredentialsExpired(false);
//        user.setAccountLocked(false);
//        user.setAccountExpired(false);
//        user.setCreationTime(new Date());
//        user.setRegistrationWay(phoneNumberRegister);
//        user = userRepository.save(user);
//        return user;
//    }
    /**
     * 根据用户姓名获取用户信息
     */
    @Override
    public UserProfile getUserByNameOfEmployeeExactly(String name) {
        QUserProfile qUserProfile =QUserProfile.userProfile;
        BooleanBuilder booleanBuilder =new BooleanBuilder();
        booleanBuilder.and(qUserProfile.realName.eq(name)).
                and(qUserProfile.deleted.eq(false)).
                and(qUserProfile.enabled.eq(true)).
                and(qUserProfile.user.userType.in(Arrays.asList(UserType.dealers, UserType.insiders)));
        Iterable<UserProfile> all = userProfileRepository.findAll(booleanBuilder);
        List<UserProfile> userProfileDOList = Lists.newArrayList(all);
//        UserProfileExample example = new UserProfileExample();
//        example.or().andUsernameEqualTo(name)
//                .andIdentityIn(Arrays.asList(User.IS_EMPLOYEE, User.DEALER));
//        List<UserProfile> userProfileDOList = userProfileDOMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(userProfileDOList)) {
            return null;
        }
        if (userProfileDOList.size() > 1) {
            throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg(name + ", 有重名工作人员"));
        }
        return userProfileDOList.get(0);
    }

    @Override
    public UserProfile getUserProfile(Long userId) {
        return userProfileRepository.findOne(userId);
//        UserProfileExample example = new UserProfileExample();
//        example.or().andUserIdEqualTo(userId);
//        List<UserProfile> userProfileDOList = userProfileDOMapper.selectByExample(example);
//        if (userProfileDOList.size() != 1) {
//            throw new BizException(
//                    EnumBizError.OPERATION_FAIL.setErrMsg("不存在id为[" + userId + "]的用户的资料"));
//        }
//        return userProfileDOList.get(0);
    }
    /**
     * Get user by id.
     *
     * @param userId id of user.
     * @return user detail information.
     */
    @Override
    public UserDetailVO getUser(Long userId) {
        UserProfile userProfileDO = getUserProfile(userId);
        Set<ModuleAuthority> userAuthorityDOList =userProfileDO.getUser().getAuthorities();
        List<BrandVO> brandVOList =new ArrayList<>();
        List<Brand> brandList = userProfileDO.getBrandList();
        for (Brand brand : brandList) {
            BrandVO brandVO =new BrandVO();
            brandVO.setId(userProfileDO.getUser().getId());
            brandVO.setBrandId(brand.getId());
            brandVO.setBrandName(brand.getBrandName());
        }
        List<LocationVO> locationVOList = new ArrayList<>();
        List<Nation> nationList = userProfileDO.getNationList();
        for (Nation nation : nationList) {
            LocationVO locationVO =new LocationVO();
            locationVO.setCode(nation.getCode());
            locationVO.setId(nation.getId());
            locationVO.setProvinceId(nation.getId());
            if (nation.getDistrict() != null) {
                locationVO.setName(nation.getDistrict());
            }
            if (nation.getProvince() != null) {
                locationVO.setName(nation.getProvince());
            }
            if (nation.getCity() != null) {
                locationVO.setName(nation.getCity());
            }
        }
        List<Station> stationList = userProfileDO.getStationList();
//        List<String> userBrandOrientations =new ArrayList<>();//品牌定位
//        for (Station station : stationList) {
//            station.getProductPosition()
//        }
//        List<String> userBrandOrientations = listUserBrandOrientationStrings(userId);
//        Map<Long, Integer> identityMap = new HashMap<>(1);
//        identityMap.put(userId, userProfileDO.getIdentity());
        List<Department> departmentList = userProfileDO.getDepartmentList();
        List<UserDepartmentVO> departmentVOList = new ArrayList<>();
        for (Department department : departmentList) {
            UserDepartmentVO userDepartmentVO =new UserDepartmentVO();
            userDepartmentVO.setDepartment(department.getName());
            userDepartmentVO.setDepartmentId(department.getId());
            userDepartmentVO.setId(department.getId());
        }
//		StationDO station = null;
//		if (Objects.nonNull(userProfileDO.getStationId())) {
//			station = stationService.getStation(userProfileDO.getStationId());
//		}
        List<UserAuthorityVO> userAuthorityVOS =new ArrayList<>();
        for (ModuleAuthority moduleAuthority : userAuthorityDOList) {
            UserAuthorityVO userAuthorityVO =new UserAuthorityVO();
            userAuthorityVO.setDescription(moduleAuthority.getDescription());
            userAuthorityVO.setAuthorityId(moduleAuthority.getId());
            userAuthorityVO.setName(moduleAuthority.getName());
            userAuthorityVO.setPlatform(PLATFORM_WECHAT);
            userAuthorityVOS.add(userAuthorityVO);
        }
        return UserDetailVO.builder()
                .employeeCode(userProfileDO.getSerialNumber())
                .identity(userProfileDO.getUser().getUserType().equals(UserType.dealers)?1:0)
                .name(userProfileDO.getRealName())
                .phone(userProfileDO.getTelephone())
//				.station(Objects.isNull(station) ? null : station.getStationName())
                .role(userProfileDO.getUser().getUserType().equals(UserType.admin)?1:0)
                .brandOrientations(new ArrayList<>())//品牌定位暂时为空
                .carBrands(brandVOList)
                .provinces(locationVOList)
                .departments(departmentVOList)
                .PCAuthorities(new ArrayList<>())
                .WeChatAuthorities(userAuthorityVOS)
                .build();
    }
}
